#ifndef Modifies_h
#define Modifies_h

#include "Standards.h"
#include "StmtTable.h"
#include "VarTable.h"
#include "ProcTable.h"
#include "Schema.h"
#include "Result.h"

/*! Modifies Class */
class Modifies {
	public:
		StmtTable* myST;
		VarTable* myVT;
		ProcTable* myPT;
		unordered_multimap<INDEX,INDEX> modifiesTableStmt;
		unordered_multimap<INDEX,set<INDEX>> modifiesTableProc;

		//! Constructor (takes in the VarTable, stmtTable, and ProcTable)
		Modifies(VarTable*, StmtTable*, ProcTable*);

		/*! 
		  A method that returns a set of statements that modify the statement in question
		  \param INDEX the statement in question
		*/
		INDEX_SET getModifiedByStmt(INDEX);

		/*! 
		  A method that returns tuples satisfying the relation with parameters provided such as Modifies(s,v)
		  \param DESIGN_ENTITY design-entity of s
		  \param NAME s
		  \param NAME v
		*/
		Schema getSynSyn(DESIGN_ENTITY, NAME, NAME);

		/*! 
		  A method that returns tuples satisfying the relation with parameters provided such as Modifies(s,"x")
		  \param DESIGN_ENTITY design-entity of s
		  \param NAME s
		  \param string "x"
		*/
		Schema getSynIdent(DESIGN_ENTITY,NAME,string);

		/*! 
		  A method that returns tuples satisfying the relation with parameters provided such as Modifies(s,_)
		  \param DESIGN_ENTITY design-entity of s
		  \param NAME s
		*/
		Schema getSynUnd(DESIGN_ENTITY,NAME);

		/*! 
		  A method that returns tuples satisfying the relation with parameters provided such as Modifies(3,v)
		  \param INDEX 3
		  \param NAME v
		*/
		Schema getIntSyn(INDEX,NAME);

		/*! 
		  A method that returns tuples satisfying the relation with parameters provided such as Modifies(3,"x")
		  \param INDEX 3
		  \param string "x"
		*/
		Schema getIntIdent(INDEX,string);

		/*! 
		  A method that returns tuples satisfying the relation with parameters provided such as Modifies(3,_)
		  \param INDEX 3
		*/
		Schema getIntUnd(INDEX);
		
		/*! 
		  A method that returns tuples satisfying the relation with parameters provided such as Modifies("Solo","x")
		  \param string "Solo"
		  \param string "x"
		*/
		Schema getIdentIdent(string,string);

		/*! 
		  A method that returns tuples satisfying the relation with parameters provided such as Modifies("Solo",v)
		  \param string "Solo"
		  \param NAME v
		*/
		Schema getIdentSyn(string,NAME);

		/*! 
		  A method that returns tuples satisfying the relation with parameters provided such as Modifies("Solo",_)
		  \param string "Solo"
		*/
		Schema getIdentUnd(string);

		/*! 
		  A method that prints modifies table for stmt
		*/
		void printAllStmt();

		/*! 
		  A method that prints modifies table for proc
		*/
		void printAllProc();

		/*! 
		  A method that inserts tuple <x,y> into Modifies table signifying y modifies x
		  \param INDEX Modifier (stmt)
		  \param INDEX Modified (variable)
		*/
		void setModifiesStmtModifies(INDEX, INDEX);

		/*! 
		  A method that inserts tuple <x,y> into Modifies table signifying y modifies x
		  \param INDEX Modifier (procedure)
		  \param INDEX Modified (variable)
		*/
		void setModifiesProcModifies(INDEX, INDEX);

	private:	
		int count;
};

#endif